package org.footballmanager.pandafootball.common.util;

import lombok.extern.slf4j.Slf4j;
import org.footballmanager.pandafootball.common.constants.Constants;

import java.text.NumberFormat;
import java.util.Random;

@Slf4j
public class IsNumeric {
    private IsNumeric() {
    }

    /**
     * 给定字符串是否为数字格式
     *
     * @param str
     * @return
     */
    public static boolean isNumeric(String str) {
        for (int i = str.length(); --i >= 0; ) {
            if (!Character.isDigit(str.charAt(i)))
                return false;
        }
        return true;
    }

    /**
     * 算法:
     * 取出数字转换为字符串,查看长度,不等于4的前面补0
     * 1位的补3个0
     * 2位的补2个0
     * 3位的补1个0
     * 4位的break
     */
    public static String getString(Integer num) {
        String result = String.valueOf(num);
        if (result.length() == 1) {
            result = "000" + result;
        } else if (result.length() == 2) {
            result = "00" + result;
        } else if (result.length() == 3) {
            result = "0" + result;
        }
        return result;
    }

    /**
     * 判断给定ip是否合法
     *
     * @param ip ip地址
     * @return true or false
     */
    public static boolean isIp(String ip) {
        boolean result = false;
        if (ip != null && !ip.isEmpty()) {
            // 定义正则表达式
            String regex = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."
                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";
            // 判断ip地址是否与正则表达式匹配
            result = ip.matches(regex);
        }
        // 返回判断信息
        return result;
    }

    /**
     * 人民币转成大写
     *
     * @param value 数值
     * @return 大写
     */
    public static String hangeToBig(double value) {
        char[] digit = {'零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'}; // 数字表示
        long midVal = (long) (value * 100); // 转化成整形
        String valStr = String.valueOf(midVal); // 转化成字符串
        String head = valStr.substring(0, valStr.length() - 2); // 取整数部分
        String rail = valStr.substring(valStr.length() - 2); // 取小数部分
        StringBuilder prefix = new StringBuilder(); // 整数部分转化的结果
        String suffix; // 小数部分转化的结果
        // 处理小数点后面的数
        if ("00".equals(rail)) { // 如果小数部分为0
            suffix = "整";
        } else {
            suffix = digit[rail.charAt(0) - '0'] + "角" + digit[rail.charAt(1) - '0'] + "分"; // 否则把角分转化出来
        }
        prefix.append(processFor(head, digit));
        if (prefix.length() > 0) {
            prefix.append("圆"); // 如果整数部分存在,则有圆的字样
        }
        return prefix + suffix; // 返回正确表示
    }

    private static String processFor(String head, char[] digit) {
        char[] hunit = {'拾', '佰', '仟'}; // 段内位置表示
        char[] vunit = {'万', '亿', '兆'}; // 段名表示
        StringBuilder prefix = new StringBuilder();
        // 处理小数点前面的数
        char[] chDig = head.toCharArray(); // 把整数部分转化成字符数组
        char zero = '0'; // 标志'0'表示出现过0
        byte zeroSerNum = 0; // 连续出现0的次数
        for (int i = 0; i < chDig.length; i++) { // 循环处理每个数字
            int idx = (chDig.length - i - 1) % 4; // 取段内位置
            int vidx = (chDig.length - i - 1) / 4; // 取段位置
            if (chDig[i] == '0') { // 如果当前字符是0
                zeroSerNum++; // 连续0次数递增
                if (zero == '0') { // 标志
                    zero = digit[0];
                } else if (idx == 0 && vidx > 0 && zeroSerNum < 4) {
                    prefix.append(String.valueOf(vunit[vidx - 1]));
                    zero = '0';
                }
                continue;
            }
            zeroSerNum = 0; // 连续0次数清零
            if (zero != '0') { // 如果标志不为0,则加上,例如万,亿什么的
                prefix.append(String.valueOf(zero));
                zero = '0';
            }
            processPrefix(prefix, digit[chDig[i] - '0'], idx, vidx, hunit[idx - 1], vunit[vidx - 1]);
        }
        return prefix.toString();
    }

    private static void processPrefix(StringBuilder prefix, char digit, int idx, int vidx, char hunit, char vunit) {
        prefix.append(String.valueOf(digit)); // 转化该数字表示
        if (idx > 0) {
            prefix.append(String.valueOf(hunit));
        }
        if (idx == 0 && vidx > 0) {
            prefix.append(String.valueOf(vunit)); // 段结束位置应该加上段名如万,亿
        }
    }

    /**
     * 根据电话和用户名获取注册码
     *
     * @param telephone
     * @param userName
     * @return
     */
    public static String getEncryptNum(String telephone, String userName) {
        String result = Constants.ERROR;
        Integer totalLength = 15;
        char[] digit = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
                'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
                'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
        Random r = new Random();
        StringBuilder sb = new StringBuilder();
        if (IsNumeric.isDigit(telephone) && IsNumeric.isLetterDigit(userName)) {
            for (int i = 0; i < totalLength; i++) {
                int randomNum = r.nextInt(digit.length);
                sb.append(digit[randomNum]);
            }
            sb.append("-");
            sb.append(telephone);
            //数字和字母是分开的
            result = sb.toString();
        }
        return result;
    }

    public static boolean isDigit(String str) {
        if (null == str || "".equals(str) || str.length() != 11) {
            return false;
        }
        return isNumeric(str);
    }

    public static boolean isLetterDigit(String str) {
        if (null == str || "".equals(str)) {
            return false;
        }
        String regex = "^[a-z0-9A-Z]+$";
        return str.matches(regex);
    }

    public static void main(String[] args) {
        log.info("65418363.32转成大写为：" + IsNumeric.hangeToBig(65418363.32));
        //System.out.println("563转成10进制为：" + IsNumeric.sixty2ten("563"))
    }

    /**
     * 给予一个Double类型的小数,返回给我一个百分比
     *
     * @param num 数字
     * @return 格式化字符串
     */
    public String getPercent(double num) {
        NumberFormat nt = NumberFormat.getPercentInstance();
        nt.setMinimumFractionDigits(0);
        return nt.format(num);
    }
}
